package com.ld.security.common.mybatis.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.ld.security.common.core.constant.CSuperConstant;
import com.ld.security.common.core.util.JsonUtil;
import com.ld.security.common.core.util.ReflectionUtil;
import com.ld.security.common.core.base.column.ListJson;
import com.ld.security.common.core.base.column.ListString;
import com.ld.security.common.core.base.column.MapJson;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.core.annotation.AnnotationUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class SimpExcelUtil {

    static final String formDate="yyyy-MM-dd HH:mm:ss";

    public static <E> byte[] getEntityWriter(Class<E> clazz,List<E> list){

       List<Map> maps =  list.stream().map(val -> {
            HashMap map =  new HashMap<>();
            for (Field field : ReflectionUtil.getAllDeclaredFields(clazz)) {
                ApiModelProperty apiModelProperty =  AnnotationUtils.findAnnotation(field,ApiModelProperty.class);
                if(apiModelProperty != null){
                    Object v =  ReflectionUtil.invokeGetter(val,field.getName());
                    if(v instanceof ListJson){
                        v = JsonUtil.toJson(v);
                    }else if(v instanceof MapJson){
                        v = JsonUtil.toJson(v);
                    }else if(v instanceof ListString){
                        v = ((ListString) v).getValue();
                    }else if(v instanceof Date){
                        Date d = (Date)v;
                        v = DateUtil.format(d,formDate);
                    }else if(v instanceof CSuperConstant.EnSuperEnum){
                        CSuperConstant.EnSuperEnum se =(CSuperConstant.EnSuperEnum) v;
                        v = se.getValue();
                    }else{
                        v = JsonUtil.toJson(v);
                    }
                    map.put(apiModelProperty.value(),v);
                }
            }
            return  map;
        }).collect(Collectors.toList());

        return getMapWriter(maps);

    }

    public static <E> byte[] getMapWriter(List<?> maps) {
        ExcelWriter writer = ExcelUtil.getWriter();

        writer.write(maps);
        ByteArrayOutputStream bs=    new ByteArrayOutputStream();
        writer.flush(bs);
        writer.close();
        return bs.toByteArray();
    }

        public static <E> List<E> getEntityReader(Class<E> clazz, File f  ){
        ExcelReader reader = ExcelUtil.getReader(f);
        List<Map<String, Object>>  all = reader.readAll();
        List<E> objs  =  all.stream().map(map -> {
            E obj = ReflectionUtil.newInstance(clazz);

            for (Field field : ReflectionUtil.getAllDeclaredFields(clazz)) {
                ApiModelProperty apiModelProperty =  AnnotationUtils.findAnnotation(field,ApiModelProperty.class);
                if(apiModelProperty != null){
                    Object val =   map.get(apiModelProperty.value());
                    Class type = field.getType();
                    if(type.equals(ListString.class)){
                        val = new ListString(val.toString());
                    }else if(type.equals(ListJson.class)){
                        val = JsonUtil.toObject(val.toString(),ListJson.class);
                    }else if(type.equals(MapJson.class)){
                        val = JsonUtil.toObject(val.toString(),MapJson.class);
                    }else if(type.equals(Date.class)){
                       val =  DateUtil.parse(val.toString(),formDate).toJdkDate();
                    }else if(type.equals(Integer.class)){
                        val =Integer.parseInt(val.toString());
                    }else if(type.equals(Double.class)){
                        val=Double.parseDouble(val.toString());
                    }else if(CSuperConstant.EnSuperEnum.class.isAssignableFrom(type)){
                        CSuperConstant.EnSuperEnum[] superEnums = (  CSuperConstant.EnSuperEnum[])type.getEnumConstants();
                        for (CSuperConstant.EnSuperEnum superEnum : superEnums) {
                            if (superEnum.getValue().equals(val)) {
                                val = superEnum;
                                break;
                            }
                        }
                    }


                    ReflectionUtil.invokeSetter(obj,field.getName(),val);


                }
            }
            return obj;
        }).collect(Collectors.toList());

        return objs;

    }



}
